# !/usr/bin/env python
# -*-coding:utf-8 -*-
# python -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple --upgrade pip

"""
取消系统标题栏, 定制窗口.

模块使用注意事项:
    1. 顶层QWidget命名为 AppWindow
    2. 顶层QFrame命名为  AppBg
    3. 标题栏命名为  Titlebar
    4. 最小化按钮命名为  BtnMin
    5. 最大化按钮命名为  BtnMaxRestore
    6. 关闭按钮命名为  BtnClose
"""

from PySide2.QtCore import Qt, QRect
from PySide2.QtGui import QColor, QEnterEvent, QIcon
from PySide2.QtWidgets import QMainWindow, QGraphicsDropShadowEffect

from conf.ui_settings import GUISet
from ui.qtui.main_ui import Ui_MainWindow
import ui.qtui.res_rc  # type: ignore


class CustomWindow(QMainWindow):

    # 初始化
    def __init__(self):
        super().__init__()
        # 导入ui文件
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.setMouseTracking(True)  # 父窗口也开启跟踪,否则只有在按下鼠标左键的时候才跟踪
        self.ui.AppWindow.setMouseTracking(True)  # 设置子窗口鼠标跟踪
        self.ui.AppBg.installEventFilter(self)  # 事件过滤器, 鼠标进入AppBg控件 过滤事件

        self.shadow = None  # 阴影
        self.direction = None  # 调整方向
        self.right_edge = None  # 右边缘
        self.bottom_edge = None  # 下边缘
        self.right_bottom_edge = None  # 右下角
        self.bottom_right_edge = None  # 下右角

        self.ui.AppWindow.setStyleSheet(GUISet.get_qss())  # 加载qss样式
        self.__set_window()  # 定制窗口
        self.__custom_titlebar()  # 定制标题栏

    # 定制窗口
    def __set_window(self):

        # 关闭系统标题栏
        self.setWindowFlags(Qt.Window | Qt.FramelessWindowHint | Qt.WindowSystemMenuHint | Qt.WindowMinimizeButtonHint
                            | Qt.WindowMaximizeButtonHint)

        # 透明背景
        self.setAttribute(Qt.WA_TranslucentBackground)

        # 边界以透明,设置边框阴影效果,否则无法定位边界
        self.shadow = QGraphicsDropShadowEffect(self)
        self.shadow.setBlurRadius(15)
        self.shadow.setColor(QColor(0, 0, 0, 150))
        self.shadow.setOffset(0, 0)
        self.ui.AppBg.setGraphicsEffect(self.shadow)

    # 定制标题栏
    def __custom_titlebar(self):

        # 移动窗口
        def move_titlebar(_event):
            if self.isMaximized():
                self.__max_restore()
            else:
                self.windowHandle().startSystemMove()

        self.ui.Titlebar.mouseMoveEvent = move_titlebar  # 信号绑定

        # 标题栏双击最大化|还原
        def doubleclick_titlebar(event):
            if event.button() == Qt.LeftButton:
                self.__max_restore()

        self.ui.Titlebar.mouseDoubleClickEvent = doubleclick_titlebar  # 信号绑定

        # 标题栏按钮 信号与槽
        self.ui.BtnMin.clicked.connect(self.showMinimized)  # 最小化
        self.ui.BtnMaxRestore.clicked.connect(self.__max_restore)  # 最大化|还原
        self.ui.BtnClose.clicked.connect(self.close)  # 关闭程序

    # 最大化|还原
    def __max_restore(self):

        if self.isMaximized():
            self.showNormal()  # 取消最大化, 正常展示
            self.ui.AppMargins.setContentsMargins(10, 10, 10, 10)  # 添加外边框
            self.ui.BtnMaxRestore.setIcon(QIcon(GUISet.btn_max))  # 更换最大化图标
        else:
            self.showMaximized()  # 窗口最大化
            self.ui.AppMargins.setContentsMargins(0, 0, 0, 0)  # 取消外边框
            self.ui.BtnMaxRestore.setIcon(QIcon(GUISet.btn_restore))  # 更换还原图标

    # 调整窗口大小(右侧|底部|右下角)
    def mousePressEvent(self, event):

        if event.button() == Qt.LeftButton:
            if self.direction == 'bottom':
                self.windowHandle().startSystemResize(Qt.BottomEdge)
            elif self.direction == 'right':
                self.windowHandle().startSystemResize(Qt.RightEdge)
            elif self.direction == 'right_bottom':
                self.windowHandle().startSystemResize(Qt.RightEdge | Qt.BottomEdge)

    # 边缘鼠标样式(右侧|底部|右下角)
    def mouseMoveEvent(self, event):

        # 边界范围(左上角x, 左上角y, 右下角x, 右下角y)
        self.right_edge = QRect(self.width() - 10, 0, self.width(), self.height() - 25)
        self.bottom_edge = QRect(0, self.height() - 10, self.width() - 25, self.height())
        self.bottom_right_edge = QRect(self.width() - 25, self.height() - 10, self.width(), self.height())
        self.right_bottom_edge = QRect(self.width() - 10, self.height() - 25, self.width(), self.height())

        # 根据鼠标在窗口的位置 改变鼠标手势
        if not self.isMaximized():

            if self.bottom_edge.contains(event.pos()):
                self.setCursor(Qt.SizeVerCursor)
                self.direction = "bottom"
            elif self.right_edge.contains(event.pos()):
                self.setCursor(Qt.SizeHorCursor)
                self.direction = "right"
            elif self.right_bottom_edge.contains(event.pos()) or self.bottom_right_edge.contains(event.pos()):
                self.setCursor(Qt.SizeFDiagCursor)
                self.direction = "right_bottom"

    # 事件过滤器, 鼠标进入其它控件后还原为标准鼠标样式, 方向属性变为None
    def eventFilter(self, obj, event):

        if isinstance(event, QEnterEvent):
            self.setCursor(Qt.ArrowCursor)
            self.direction = None
        return super().eventFilter(obj, event)
